feat(cache): restore output files on cache hit#321
feat(cache): restore output files on cache hit#321branchseer wants to merge 1 commit intofeat/output-globsfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 79f428a501
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let needs_fspy = cache_metadata.input_config.includes_auto | ||
| || cache_metadata.output_config.includes_auto; |
There was a problem hiding this comment.
Separate input/output negative filters for auto tracking
This now enables fspy whenever output_config.includes_auto is true, but the filter passed to path tracking is still derived only from input_config.negative_globs, so writes that match input negatives are dropped before output archiving. In execute_spawn, a config like input: [{auto:true}, "!dist/**"] with default auto output will never record dist/** writes in path_writes, causing cache hits to replay logs but fail to restore expected output files.
Useful? React with 👍 / 👎.
| sorted_files.sort(); | ||
|
|
||
| // Create archive with UUID filename | ||
| let archive_name: Str = vite_str::format!("{}.tar.zst", uuid::Uuid::new_v4()); |
There was a problem hiding this comment.
Clean up superseded output archives on cache overwrite
A fresh UUID archive filename is generated on every successful cache write, but the previous archive file is never removed when the same cache key is updated, so old tarballs become orphaned. Re-running tasks over time will continuously accumulate stale *.tar.zst files in the cache directory and can cause unbounded disk growth even though only the latest archive is reachable from cache.db.
Useful? React with 👍 / 👎.
Archives output files after a successful run and restores them on cache hit. Defaults to automatically tracking files the task writes; accepts globs (e.g. `"dist/**"`), `{ "auto": true }`, and negative patterns (`"!dist/cache/**"`).
Squashed rebase of #321 onto main after the spawn decompose refactor and wincode migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9de20eb to
b020bf5
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b020bf53ba
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pub input_config: ResolvedGlobConfig, | ||
| /// Resolved output configuration that affects cache restoration. | ||
| /// Glob patterns are workspace-root-relative. | ||
| pub output_config: ResolvedGlobConfig, |
There was a problem hiding this comment.
Bump cache schema version after key/value layout change
Adding output_config to CacheEntryKey and output_archive to CacheEntryValue changes the serialized blob format, but load_from_path still treats schema version 11 as current. On upgrade with an existing cache.db, old rows are deserialized with the new schema in get_cache_key_by_execution_key/get_by_cache_key, which can fail and surface as a cache lookup error that fails task execution instead of cleanly missing. Please version-bump and reset/migrate old cache rows.
Useful? React with 👍 / 👎.
| if metadata.input_config.includes_auto || metadata.output_config.includes_auto { | ||
| // Resolve input negative globs for fspy path filtering |
There was a problem hiding this comment.
Avoid inferring input reads when only output auto is enabled
This enables fspy whenever output auto-tracking is on (which is the default when output is omitted), even if input auto-tracking is disabled. The later post-run fingerprint path still consumes path_reads, so tasks that set input: [] or explicit-only inputs unexpectedly regain inferred input dependencies and can miss cache hits due to unrelated reads. Read fingerprinting should remain gated by input_config.includes_auto.
Useful? React with 👍 / 👎.
| .input_config | ||
| .negative_globs | ||
| .iter() |
There was a problem hiding this comment.
Stop filtering output auto writes with input negatives
The fspy filter is built from input_config.negative_globs, but TrackedPathAccesses::from_raw applies that filter to writes as well as reads. If a task excludes dist/** from inputs (a common pattern) and relies on default output auto-tracking, writes under dist are dropped before archiving, so cache hits won't restore those outputs. Output write collection needs filtering based on output_config negatives, not input negatives.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Adds output file archiving/restoration to the task execution cache so cache hits can restore build artifacts (e.g., dist/) in addition to replaying stdout/stderr.
Changes:
- Introduces an
outputcache config (same glob/auto/negative semantics asinput) and includes it in cache keys/metadata. - Archives resolved output files into
tar.zston successful cache updates and extracts them on cache hits. - Updates docs and regenerates plan/e2e snapshots to reflect the new cache behavior and schema.
Reviewed changes
Copilot reviewed 102 out of 103 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| docs/output-restoration.md | New user-facing documentation for output restoration. |
| docs/output-restoration-research.md | Research notes on build-tool compatibility/edge cases. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_self_reference/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_no_package_json/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_mutual_recursion/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_multi_command/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_depends_on_passthrough/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace_root_cd_no_skip/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/vpr_shorthand/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/transitive_skip_intermediate/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_in_subpackage/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_in_subpackage/snapshots/query_synthetic_in_subpackage.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/query_task_with_cache_true_enables_synthetic_cache.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/query_task_untrackedEnv_inherited_by_synthetic.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/query_script_cache_false_does_not_affect_expanded_synthetic_cache.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/synthetic_cache_disabled/snapshots/query_parent_cache_false_does_not_affect_expanded_query_tasks.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/shell_fallback/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/shell_fallback/snapshots/query_shell_fallback_for_pipe_command.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/script_hooks_task_no_hook/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/script_hooks_nested_run/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/script_hooks_disabled/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/script_hooks/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/recursive_topological_workspace/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/pnpm_workspace_packages_optional/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/parallel_and_concurrency/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/package_self_dependency/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_tasks/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_cache_override/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_cache_override/snapshots/query_outer___no_cache_does_not_propagate_into_nested___cache.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_cache_override/snapshots/query_outer___cache_propagates_to_nested_run_without_flags.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/nested_cache_override/snapshots/query_nested___cache_enables_inner_task_caching.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/input_workspace_base/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/input_trailing_slash/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/filter_workspace/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/extra_args_not_forwarded_to_depends_on/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/extra_args_not_forwarded_to_depends_on/snapshots/query_extra_args_only_reach_requested_task.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/explicit_deps_workspace/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/empty_package_test/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/duplicate_package_names/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/dependency_both_topo_and_explicit/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cycle_dependency/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/conflict_test/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/comprehensive_task_graph/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cd_in_scripts/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cd_in_scripts/snapshots/query_cd_before_vt_run_should_not_affect_expanded_task_cwd.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cd_in_scripts/snapshots/query_cd_before_vt_lint_should_put_synthetic_task_under_cwd.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_true_no_force_enable/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_true_no_force_enable/snapshots/query_task_cached_when_global_cache_true.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_true_no_force_enable/snapshots/query_script_cached_when_global_cache_true.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_tasks_disabled/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_subcommand/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_sharing/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_task_override/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_task_override/snapshots/query_task_cached_by_default.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_task_override/snapshots/query_another_task_cached_by_default.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_enabled/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_scripts_default/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_synthetic_task_with_extra_args_in_user_task.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_synthetic_task_in_user_task_with_cwd.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_synthetic_task_in_user_task.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_normal_task_with_extra_args.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_lint_and_echo_with_extra_args.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_keys/snapshots/query_echo_and_lint_with_extra_args.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_cli_override/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_cli_override/snapshots/query___cache_on_task_with_per_task_cache_true_enables_caching.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_cli_override/snapshots/query___cache_enables_task_caching_even_when_cache_tasks_is_false.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/cache_cli_override/snapshots/query___cache_enables_script_caching.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/additional_env/snapshots/task_graph.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/tests/plan_snapshots/fixtures/additional_env/snapshots/query_tool_synthetic_task_in_user_task.jsonc | Snapshot updated to include output_config. |
| crates/vite_task_plan/src/plan.rs | Plumbs output_config into planned cache metadata. |
| crates/vite_task_plan/src/cache_metadata.rs | Adds output_config to CacheMetadata. |
| crates/vite_task_graph/src/config/user.rs | Adds user-facing output field to cache config. |
| crates/vite_task_graph/src/config/mod.rs | Resolves output_config; renames to ResolvedGlobConfig. |
| crates/vite_task_graph/run-config.ts | Updates TS run-config schema to include output. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/vite-task.json | New e2e fixture covering output restoration modes. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/src/main.ts | Fixture source file for cache invalidation tests. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/output_config_change_invalidates_cache.md | New snapshot: output config change invalidates cache. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/negative_output___excluded_files_not_restored.md | New snapshot: negative output globs exclude restoration. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/glob_output___only_matched_files_restored.md | New snapshot: glob outputs restore matched files only. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/auto_output_with_non_auto_input.md | New snapshot: auto output with explicit input globs. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots/auto_output___files_restored_on_cache_hit.md | New snapshot: auto output restored on cache hit. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/snapshots.toml | Adds e2e scenarios for output restoration. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/output_cache_test/package.json | Adds fixture package manifest. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/input_cache_test/snapshots/positive_globs___hit_on_read_but_unmatched_file.md | Snapshot updated for new cache behavior. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/input_cache_test/snapshots/fspy_env___not_set_when_auto_inference_disabled.md | Snapshot updated for new FSPY behavior. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/input_cache_test/snapshots/folder_input___hit_despite_file_changes_and_folder_deletion.md | Snapshot updated for new cache behavior. |
| crates/vite_task_bin/tests/e2e_snapshots/fixtures/input_cache_test/snapshots/empty_input___hit_despite_file_changes.md | Snapshot updated for new cache behavior. |
| crates/vite_task_bin/src/vtt/write_file.rs | Ensures parent dirs exist before writing fixture files. |
| crates/vite_task_bin/src/lib.rs | Adds output: None to default task cache config. |
| crates/vite_task/src/session/reporter/summary.rs | Treats OutputConfig mismatch as config-changed in summary. |
| crates/vite_task/src/session/mod.rs | Passes cache directory path into execution layer. |
| crates/vite_task/src/session/execute/mod.rs | Implements archive creation/extraction and output collection. |
| crates/vite_task/src/session/execute/glob_inputs.rs | Adds helper to collect globbed paths for outputs. |
| crates/vite_task/src/session/cache/mod.rs | Adds output_config to cache keys; stores output_archive. |
| crates/vite_task/src/session/cache/display.rs | Displays output-config cache-miss reason inline. |
| crates/vite_task/src/session/cache/archive.rs | New tar+zstd archive create/extract helpers. |
| crates/vite_task/docs/task-cache.md | Partially updates cache docs for ResolvedGlobConfig. |
| crates/vite_task/Cargo.toml | Adds dependencies for archiving (tar/uuid/zstd). |
| Cargo.toml | Adds workspace dependency for zstd. |
| Cargo.lock | Updates lockfile for new deps and version bumps. |
| CHANGELOG.md | Notes new output field and output restoration behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let fspy = | ||
| if metadata.input_config.includes_auto || metadata.output_config.includes_auto { | ||
| // Resolve input negative globs for fspy path filtering | ||
| // (already workspace-root-relative). Output negatives are applied | ||
| // later in `collect_and_archive_outputs`. | ||
| match metadata | ||
| .input_config | ||
| .negative_globs | ||
| .iter() | ||
| .map(|p| Ok(wax::Glob::new(p.as_str())?.into_owned())) | ||
| .collect::<anyhow::Result<Vec<_>>>() | ||
| { | ||
| Ok(negs) => Some(negs), | ||
| Err(err) => { | ||
| leaf_reporter.finish( | ||
| None, | ||
| CacheUpdateStatus::NotUpdated(CacheNotUpdatedReason::CacheDisabled), | ||
| Some(ExecutionError::PostRunFingerprint(err)), | ||
| ); | ||
| return SpawnOutcome::Failed; | ||
| } | ||
| } | ||
| } | ||
| } else { | ||
| None | ||
| }; | ||
| } else { | ||
| None | ||
| }; |
There was a problem hiding this comment.
fspy is enabled when either input_config.includes_auto or output_config.includes_auto is true, but the cache update path still fingerprints all fspy reads. This makes "output auto" implicitly re-enable inferred input tracking even when the user disabled input auto, causing unexpected cache misses (and contradicting the stated input/output independence). Consider only using fspy reads for post-run fingerprinting when input_config.includes_auto is true, while still using fspy writes for output archiving.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
0008bd7 to
994624a
Compare
Archives output files after a successful run and restores them on cache hit. Defaults to automatically tracking files the task writes; accepts globs (e.g. `"dist/**"`), `{ "auto": true }`, and negative patterns (`"!dist/cache/**"`).
Squashed rebase of #321 onto main after the spawn decompose refactor and wincode migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
589a626 to
9df3054
Compare
9df3054 to
3a8b605
Compare
Squashed rebase of 51 commits from runner-aware-tools branch onto feat/output-restoration. Original commit history preserved on the ras-backup ref for reference. Key features bundled: - vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr) - vite_task_server: per-task IPC server (Handler trait + Recorder) - vite_task_client: sync Rust client - vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper - vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH; bundle with fspy via Tracking struct; materialize .node addon on first use - consume runner-aware tool reports for cache decisions: * disableCache() short-circuits via ToolRequested * ignoreInput / ignoreOutput filter fspy reads/writes * tracked: true env / env-glob records folded into PostRunFingerprint - IPC server failure surfaces via IpcServerError; cache update is skipped - schema bumped to user_version = 13 (CacheEntryKey carries output_config, CacheEntryValue carries output_archive + tracked envs) Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321 output archiving, input-negative reads-only filter): TrackingOutcome post-run summary preserved alongside Tracking pre-run handle; auto-input reads gated on input_config.includes_auto and filtered by input negatives + ignoreInput; auto-output writes filtered by negatives + ignoreOutput. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9dbd5b8 to
6d03bc0
Compare
Adds `{ auto: true }` support to the `output` field, plus the implicit
default: when `output` is omitted, automatically tracks files the task
writes (via fspy) and archives them. Explicit globs and `auto` can be
mixed in the same array.
Also includes:
- `read_write_overlap` check: if a task writes to a file it also read
(auto-inferred), the cache update is skipped (`InputModified`).
Prerun input hashes would otherwise be stale.
- Input negatives apply to reads only, not writes — keeps `input: ["!dist/**"]`
from accidentally dropping writes to `dist/**` during archiving.
- Input-auto gating: when `input_config.includes_auto` is false, fspy
reads do not contribute to the post-run fingerprint, even when fspy
is enabled solely for output tracking.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3a8b605 to
6198f6b
Compare
Squashed rebase of 51 commits from runner-aware-tools branch onto feat/output-restoration. Original commit history preserved on the ras-backup ref for reference. Key features bundled: - vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr) - vite_task_server: per-task IPC server (Handler trait + Recorder) - vite_task_client: sync Rust client - vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper - vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH; bundle with fspy via Tracking struct; materialize .node addon on first use - consume runner-aware tool reports for cache decisions: * disableCache() short-circuits via ToolRequested * ignoreInput / ignoreOutput filter fspy reads/writes * tracked: true env / env-glob records folded into PostRunFingerprint - IPC server failure surfaces via IpcServerError; cache update is skipped - schema bumped to user_version = 13 (CacheEntryKey carries output_config, CacheEntryValue carries output_archive + tracked envs) Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321 output archiving, input-negative reads-only filter): TrackingOutcome post-run summary preserved alongside Tracking pre-run handle; auto-input reads gated on input_config.includes_auto and filtered by input negatives + ignoreInput; auto-output writes filtered by negatives + ignoreOutput. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Squashed rebase of 51 commits from runner-aware-tools branch onto feat/output-restoration. Original commit history preserved on the ras-backup ref for reference. Key features bundled: - vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr) - vite_task_server: per-task IPC server (Handler trait + Recorder) - vite_task_client: sync Rust client - vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper - vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH; bundle with fspy via Tracking struct; materialize .node addon on first use - consume runner-aware tool reports for cache decisions: * disableCache() short-circuits via ToolRequested * ignoreInput / ignoreOutput filter fspy reads/writes * tracked: true env / env-glob records folded into PostRunFingerprint - IPC server failure surfaces via IpcServerError; cache update is skipped - schema bumped to user_version = 13 (CacheEntryKey carries output_config, CacheEntryValue carries output_archive + tracked envs) Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321 output archiving, input-negative reads-only filter): TrackingOutcome post-run summary preserved alongside Tracking pre-run handle; auto-input reads gated on input_config.includes_auto and filtered by input negatives + ignoreInput; auto-output writes filtered by negatives + ignoreOutput. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Squashed rebase of 51 commits from runner-aware-tools branch onto feat/output-restoration. Original commit history preserved on the ras-backup ref for reference. Key features bundled: - vite_task_ipc_shared: shared protocol (Request/GetEnvResponse, NativeStr) - vite_task_server: per-task IPC server (Handler trait + Recorder) - vite_task_client: sync Rust client - vite_task_client_napi + @voidzero-dev/vite-task-client: node addon + JS wrapper - vite_task: wire IPC server into spawn; inject VP_IPC + VP_RUN_NODE_CLIENT_PATH; bundle with fspy via Tracking struct; materialize .node addon on first use - consume runner-aware tool reports for cache decisions: * disableCache() short-circuits via ToolRequested * ignoreInput / ignoreOutput filter fspy reads/writes * tracked: true env / env-glob records folded into PostRunFingerprint - IPC server failure surfaces via IpcServerError; cache update is skipped - schema bumped to user_version = 13 (CacheEntryKey carries output_config, CacheEntryValue carries output_archive + tracked envs) Conflicts resolved against post-rebase main (#352 cfg(fspy) gating, #321 output archiving, input-negative reads-only filter): TrackingOutcome post-run summary preserved alongside Tracking pre-run handle; auto-input reads gated on input_config.includes_auto and filtered by input negatives + ignoreInput; auto-output writes filtered by negatives + ignoreOutput. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Previously, a cache hit only replayed terminal output (stdout/stderr). Build artifacts like
dist/were not restored, so downstream tasks or users had to re-run even on a cache hit.Now, output files written during task execution are archived and restored automatically. The
outputfield reuses the same config types and resolution logic asinput(renamedResolvedInputConfig→ResolvedGlobConfigto reflect this).Config examples:
Test plan
cargo clippy -- -D warningsclean🤖 Generated with Claude Code